﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;

namespace Kyoh.Lib.WinForms
{
    /// <summary>入力を記憶し、選択肢として表示する <see cref="ComboBox"/> の拡張。</summary>
    public class HistComboBox : ComboBox
    {
        private void SaveHistory()
        {
            // 入力値の取得と履歴化の補正
            var inputed = Text;
            if (inputed == null)
                return;
            var handler = AddingHistory;
            var history = new AddingHistoryEventArgs {AddingHistory = inputed};
            if (handler != null)
                handler.BeginInvoke(this, history, null, null);
            if (history.AddingHistory == null)
                return;

            // 自動補完リスト項目に追加
            if (Items.Contains(history.AddingHistory))
                Items.Remove(history.AddingHistory);
            Items.Insert(0, history.AddingHistory);
            while (Items.Count > 0 && Items.Count > MaxDropDownItems)
                Items.RemoveAt(Items.Count - 1);

            // 入力値の戻し
            Text = history.AddingHistory;
        }

        /// <summary><see cref="System.Windows.Forms.Control.Validating"/> イベントを発生させます。</summary>
        protected override void OnValidating(CancelEventArgs e)
        {
            var text = Text;
            base.OnValidating(e);
            Text = text;
        }

        /// <summary><see cref="System.Windows.Forms.Control.Validated"/> イベントを発生させます。</summary>
        protected override void OnValidated(EventArgs e)
        {
            base.OnValidated(e);

            // フォーカスの移動先を取得
            var form = FindForm();
            if (form == null)
                return;
            var focused = form.ActiveControl;

            SaveHistory();

            // フォーカスの移動
            form.ActiveControl = focused;
        }

        /// <summary><see cref="AddingHistory"/> イベントの引数。</summary>
        public class AddingHistoryEventArgs : EventArgs
        {
            /// <summary><see cref="HistComboBox"/>に追加する履歴項目の値を取得または設定します。</summary>
            public string AddingHistory { get; set; }
        }

        /// <summary><see cref="HistComboBox"/> に新しい履歴項目が追加される際に発生するイベント。</summary>
        public event EventHandler<AddingHistoryEventArgs> AddingHistory;
    }
}